﻿using System.Collections.Generic;
using System.ComponentModel;

namespace WCFServerService
{
	public class ClientQueue : INotifyPropertyChanged
	{
		#region Members 

		static protected readonly object lockObject = new object();

		// Queue Number and QueueItem
		List<QueueItem> queue = new List<QueueItem>();

		#endregion 

		#region Public Functions

		public bool IsEmpty()
		{
			return Queue.Count == 0;
		}

		public void Clear()
		{
			lock (lockObject)
			{
				foreach (QueueItem queueItem in Queue)
					queueItem.PropertyChanged -= PropertyChangedEvent;

				Queue.Clear();
			}

			OnPropertyChanged("ClientsQueue.Queue.Changed");
		}

		public void Remove(QueueItem queueItem)
		{
			lock (lockObject)
			{
				QueueItem _queueItem = GetItem(queueItem.GroupName, queueItem.ClientName);
				if (_queueItem != null)
				{
					Queue.Remove(_queueItem);
				}
				else
				{
					return;
				}
			}

			OnPropertyChanged("ClientsQueue.Queue.Changed");
		}

		public void Update(string groupName, string clientName, string pushMessageBoxAddress)
		{
			lock (lockObject)
			{
				QueueItem _queueItem = GetItem(groupName, clientName);
				if (_queueItem != null)
				{
					_queueItem.PushMessageBoxAddress = pushMessageBoxAddress;
				}
				else
				{
					throw new System.Exception("Client item does not exists");
				}
			}
		}
		
		public void Add(QueueItem queueItem)
		{
			lock (lockObject)
			{
				QueueItem _queueItem = GetItem(queueItem.GroupName, queueItem.ClientName);

				if (_queueItem != null)
				{
					if(_queueItem.PushMessageBoxAddress == queueItem.PushMessageBoxAddress)
						return;
					else
						throw new System.Exception("Client item already exist in queue with different address");
				}
				else
				{
					Queue.Add(queueItem);
					queueItem.PropertyChanged += PropertyChangedEvent;
				}
			}

			OnPropertyChanged("ClientsQueue.Queue.Changed");
		}


		public QueueItem GetItem(string groupName, string clientName)
		{
			foreach (QueueItem _queueItem in Queue)
			{
				if ((_queueItem.GroupName == groupName) &&
					(_queueItem.ClientName == clientName))
					return _queueItem;
			}

			return null;
		}

		public bool IsInQueue(string groupName, string clientName)
		{
			return (GetItem(groupName, clientName) != null);
		}

		public IEnumerator<QueueItem> GetEnumerator()
		{
			return Queue.GetEnumerator();
		}

		#endregion 

		#region Internal Functions

		protected List<QueueItem> Queue
		{
			get {return queue;}
		}

		void PropertyChangedEvent(object sender, PropertyChangedEventArgs e)
		{
			PropertyChangedEventHandler handler = this.PropertyChanged;
			if (handler != null)
				handler(sender, e);
		}

		#endregion

		#region INotifyPropertyChanged Members

		public event PropertyChangedEventHandler PropertyChanged;

		public void OnPropertyChanged(string propertyName)
		{
			PropertyChangedEventHandler handler = this.PropertyChanged;
			if (handler != null)
				handler(this, new PropertyChangedEventArgs(propertyName));
		}

		#endregion
	}
}
